import { Box, Button, Checkbox, IconButton, InputAdornment, Table, TableBody, TableContainer, TableFooter, TableHead, TableRow, TextField } from '@mui/material';
import React, { JSX } from 'react';
import { NulHeaderTableCell, NulTableCell } from '../../components/NulHeaderTable';
import { removeElementFromArray } from '../../util/Arrays';
import ClearIcon from '@mui/icons-material/Clear';
import EditIcon from '@mui/icons-material/Edit';
import DeleteIcon from '@mui/icons-material/Delete';
import { ReactComponent as SearchIcon } from '../../assets/search.svg';
import { ReactComponent as CreateIcon } from '../../assets/create.svg';
import AirlineStopsIcon from '@mui/icons-material/AirlineStops';
import AutorenewIcon from '@mui/icons-material/Autorenew';
import { commodityManagementActions, selectCommodityEntries, selectCommodityEntriesLoaded } from '../../actions/CommodityManagement';
import { inventoryManagementActions, selectInventoryEntries, selectInventoryEntriesLoaded, selectInventoryWarehouseId } from '../../actions/InventoryManagement';
import { selectSupplierEntries, selectSupplierEntriesLoaded, supplierManagementActions } from '../../actions/SupplierManagement';
import { selectWarehouseEntries, selectWarehouseEntriesLoaded, warehouseManagementActions } from '../../actions/WarehouseManagement';
import { useAppDispatch, useAppSelector } from '../../actions/hooks';
import { InventoryEntry, int } from '../../types';
import { CreateInventory } from './CreateInventoryDialog';
import { ModifyInventory } from './ModifyInventoryDialog';
import SwitchInventoryDialog from './SwitchInventoryDialog';
import TransferInventoryDialog from './TransferInventoryDialog';

interface InventoryManagementProps {

}

function InventoryManagement(props: InventoryManagementProps): JSX.Element {

  const [filterValue, setFilterValue] = React.useState<string>('');
  const [openInventoryDialog, setOpenInventoryDialog] = React.useState<boolean>(false);
  const [openModifyDialog, setOpenModifyDialog] = React.useState<boolean>(false);
  const [openSwitchDialog, setOpenSwitchDialog] = React.useState<boolean>(false);
  const [openTransferDialog, setOpenTransferDialog] = React.useState<boolean>(false);

  const [checkedIdList, setCheckedIdList] = React.useState<number[]>([]);
  const [modifyEntry, setModifyEntry] = React.useState<InventoryEntry>({
    id: 0, quantity: 0, supplierName: '', costPrice: 0, commodityId: 0, commodityName: ''
  });

  const dispatch = useAppDispatch();

  const warehouseEntriesLoaded = useAppSelector(selectWarehouseEntriesLoaded);
  const warehouseEntries = useAppSelector(selectWarehouseEntries);
  const inventoryEntries = useAppSelector(selectInventoryEntries);
  const inventoryEntriesLoaded = useAppSelector(selectInventoryEntriesLoaded);
  const inventoryWarehouseId = useAppSelector(selectInventoryWarehouseId);
  const supplierEntriesLoaded = useAppSelector(selectSupplierEntriesLoaded);
  const supplierEntries = useAppSelector(selectSupplierEntries);
  const commodityEntries = useAppSelector(selectCommodityEntries);
  const commodityEntriesLoaded = useAppSelector(selectCommodityEntriesLoaded);

  const getSelectedEntries = () => {
    const result: InventoryEntry[] = [];
    for (let i = 0; i < checkedIdList.length; ++i) {
      const find = inventoryEntries.find((value) => value.id === checkedIdList[i]);
      if (find !== undefined) {
        result.push(find);
      }
    }
    return result;
  };

  React.useEffect(() => {
    if (!supplierEntriesLoaded) {
      dispatch(supplierManagementActions.getSupplier({}));
    }
    if (!commodityEntriesLoaded) {
      dispatch(commodityManagementActions.getCommodities({}));
    }
    if (!warehouseEntriesLoaded) {
      dispatch(warehouseManagementActions.getWarehouses({}));
    }
  });

  React.useEffect(() => {
    if (warehouseEntriesLoaded) {
      if (warehouseEntries.length > 0) {
        dispatch(inventoryManagementActions.switch({ warehouseId: warehouseEntries[0].id }));
      }
    }
  }, [warehouseEntriesLoaded, warehouseEntries, dispatch]);

  React.useEffect(() => {
    if (!inventoryEntriesLoaded && inventoryWarehouseId !== 0) {
      dispatch(inventoryManagementActions.getInventory({ warehouseId: inventoryWarehouseId, name: filterValue }));
    }
  }, [inventoryEntriesLoaded, inventoryWarehouseId, filterValue, dispatch]);

  React.useEffect(() => {
    dispatch(inventoryManagementActions.refresh());
  }, [filterValue, dispatch]);

  const handleModify = (row: InventoryEntry) => {
    setModifyEntry(row);
    setOpenModifyDialog(true);
  };

  const handleDelete = (row: InventoryEntry) => {
    dispatch(inventoryManagementActions.deleteInventory({ id: [row.id], warehouseId: inventoryWarehouseId }));
  };

  const handleBatchDelete = () => {
    dispatch(inventoryManagementActions.deleteInventory({ id: checkedIdList, warehouseId: inventoryWarehouseId }));
  }

  const handleSwitchResult = (id: number) => {
    const index: number = warehouseEntries.findIndex(value => value.id === id);
    if (index !== -1) {
      setCheckedIdList([]);
      dispatch(inventoryManagementActions.switch({ warehouseId: id }));
    }
  };

  const headerChecked: boolean = checkedIdList.length !== 0 && checkedIdList.length === inventoryEntries.length;
  const headerIndeterminate: boolean = checkedIdList.length !== 0 && checkedIdList.length < inventoryEntries.length;

  return (
    <>
      <Box sx={{ padding: '30px 30px 30px 30px', flex: 'none', flexGrow: 1, display: 'flex', flexDirection: 'column', height: '100%', boxSizing: 'border-box' }}>
        <Box>
          <Box sx={{
            fontFamily: 'Open Sans',
            fontStyle: 'normal',
            fontWeight: 600,
            fontSize: '22px',
            lineHeight: '125%',
            display: 'flex',
            flexDirection: 'row'
          }}>
            <Box>
              Inventory Management
            </Box>
            <Button
              startIcon={<AutorenewIcon />} sx={{ marginLeft: '10px', textTransform: 'none' }}
              onClick={() => { setOpenSwitchDialog(true); }}
            >
              {warehouseEntries.find(item => item.id === inventoryWarehouseId)?.name}
            </Button>
          </Box>
          <Box sx={{
            marginTop: '20px', width: '100%', height: '40px', display: 'flex',
            flexDirection: 'row', justifyContent: 'space-between'
          }}>
            <Box sx={{ width: '456px' }}>
              <TextField
                size='small'
                fullWidth={true}
                InputProps={{
                  startAdornment: (
                    <InputAdornment position='start' sx={{}}>
                      <SearchIcon />
                    </InputAdornment>
                  ),
                  endAdornment: (
                    <IconButton edge="end" onClick={() => { setFilterValue(''); }}>
                      <ClearIcon fontSize='small' />
                    </IconButton>
                  )
                }}
                placeholder='Search inventory'
                value={filterValue}
                onChange={(action) => { setFilterValue(action.target.value); }}
                sx={{
                  paddingLeft: '0px'
                }}
              />
            </Box>
            <Box sx={{
              flex: 'none',
              order: 1,
              flexGrow: 0,
            }}>
              <Button
                variant="outlined"
                disableElevation
                startIcon={<AirlineStopsIcon />}
                onClick={() => {
                  setOpenTransferDialog(true);
                }}
                sx={{
                  height: '40px',
                  textTransform: 'none',
                  marginRight: '10px',
                  minWidth: '110px'
                }}
              >
                Transfer
              </Button>
              <Button
                variant="contained"
                disableElevation
                startIcon={<DeleteIcon />}
                color='error'
                onClick={handleBatchDelete}
                sx={{
                  height: '40px',
                  textTransform: 'none',
                  marginRight: '10px',
                  minWidth: '95px'
                }}
              >
                Delete
              </Button>
              <Button
                variant="contained"
                disableElevation
                startIcon={<CreateIcon />}
                onClick={() => {
                  setOpenInventoryDialog(true);
                }}
                sx={{
                  height: '40px',
                  textTransform: 'none',
                  minWidth: '95px'
                }}
              >
                Stock
              </Button>
            </Box>
          </Box>
        </Box>
        <Box sx={{
          marginTop: '20px',
          width: '100%',
          height: '100%'
        }}>
          <TableContainer
            sx={{
              width: '100%',
              height: '100%'
            }}
          >
            <Table
              stickyHeader
              sx={{
                border: '1px solid #DFE4E8',
                borderRadius: '8px',
                fontFamily: 'Open Sans',
                fontStyle: 'normal',
                display: 'flex',
                flexDirection: 'column',
                height: '100%'
              }}
            >
              <TableHead sx={{ border: '8px 8px 0px 0px' }}>
                <TableRow sx={{
                  height: '42px',
                  padding: 0,
                  width: '100%',
                  display: 'flex',
                  alignItems: 'center',
                }}>
                  <Box sx={{ height: '100%' }}>
                    <NulHeaderTableCell
                      sx={{
                        width: '62px',
                        borderTopLeftRadius: '8px',
                        justifyContent: 'center',
                        flexGrow: 0
                      }}
                    >
                      <Checkbox
                        sx={{
                          width: '42px',
                          display: 'flex',
                          justifyContent: 'center',
                        }}
                        onClick={() => {
                          if (headerChecked) {
                            setCheckedIdList([]);
                          }
                          else {
                            setCheckedIdList(inventoryEntries.map(entry => entry.id));
                          }
                        }}
                        checked={headerChecked}
                        indeterminate={headerIndeterminate}
                      />
                    </NulHeaderTableCell>
                  </Box>
                  <Box sx={{ display: 'flex', flexDirection: 'row', flexGrow: 1, position: 'relative', height: '100%' }}>
                    <NulHeaderTableCell sx={{ width: '5%' }}>
                      ID
                    </NulHeaderTableCell>
                    <NulHeaderTableCell sx={{ width: '20%' }}>
                      Name
                    </NulHeaderTableCell>
                    <NulHeaderTableCell sx={{ width: '15%' }}>
                      Quantity
                    </NulHeaderTableCell>
                    <NulHeaderTableCell sx={{ width: '20%' }}>
                      Supplier
                    </NulHeaderTableCell>
                    <NulHeaderTableCell sx={{ width: '15%' }}>
                      Cost Price
                    </NulHeaderTableCell>
                    <NulHeaderTableCell sx={{ width: '25%', borderTopRightRadius: '8px' }}>
                      Operations
                    </NulHeaderTableCell>
                  </Box>
                </TableRow>
              </TableHead>
              <TableBody
                sx={{
                  flexGrow: 1, display: 'block', overflowY: 'auto'
                }}
              >
                {inventoryEntries.map(row => {
                  const checkedIndex: number = checkedIdList.indexOf(row.id);
                  return (
                    <TableRow
                      key={row.id}
                      sx={{
                        width: '100%',
                        display: 'flex',
                        alignItems: 'center',
                        height: '42px'
                      }}
                    >
                      <Box sx={{ height: '100%' }}>
                        <NulTableCell sx={{ width: '62px', justifyContent: 'center', flexGrow: 0 }}>
                          <Checkbox
                            sx={{
                              width: '42px',
                              display: 'flex',
                              justifyContent: 'center',
                            }}
                            checked={checkedIndex !== -1}
                            onChange={(event, checked) => {
                              if (checked) {
                                if (checkedIndex === -1) {
                                  setCheckedIdList([...checkedIdList, row.id]);
                                }
                              }
                              else {
                                if (checkedIndex !== -1) {
                                  setCheckedIdList(removeElementFromArray(checkedIdList, checkedIndex));
                                }
                              }
                            }}
                          />
                        </NulTableCell>
                      </Box>
                      <Box sx={{ display: 'flex', flexDirection: 'row', flexGrow: 1, position: 'relative', height: '100%' }}>
                        <NulTableCell sx={{ width: '5%' }}>
                          {row.id}
                        </NulTableCell>
                        <NulTableCell sx={{ width: '20%' }}>
                          {row.commodityName}
                        </NulTableCell>
                        <NulTableCell sx={{ width: '15%' }}>
                          {row.quantity}
                        </NulTableCell>
                        <NulTableCell sx={{ width: '20%' }}>
                          {row.supplierName}
                        </NulTableCell>
                        <NulTableCell sx={{ width: '15%' }}>
                          {row.costPrice}
                        </NulTableCell>
                        <NulTableCell sx={{ width: '25%', display: 'flex' }}>
                          <IconButton aria-label='edit' onClick={() => { handleModify(row); }}>
                            <EditIcon />
                          </IconButton>
                          <IconButton aria-label='delete' onClick={() => { handleDelete(row); }}>
                            <DeleteIcon />
                          </IconButton>
                        </NulTableCell>
                      </Box>
                    </TableRow>
                  );
                })}
              </TableBody>
              <TableFooter
                sx={{
                  minHeight: '34px',
                  maxHeight: '44px',
                  display: 'block',
                  backgroundColor: '#F1F3F5',
                  borderRadius: '0px 0px 8px 8px',
                }}
              ></TableFooter>
            </Table>
          </TableContainer>
        </Box>
      </Box>
      <SwitchInventoryDialog
        open={openSwitchDialog}
        onClose={() => { setOpenSwitchDialog(false); }}
        onResult={handleSwitchResult}
        warehouseEntries={warehouseEntries}
      />
      <TransferInventoryDialog
        open={openTransferDialog}
        onClose={() => { setOpenTransferDialog(false); }}
        selectedInventories={getSelectedEntries()}
        warehouseEntries={warehouseEntries}
        warehouseId={inventoryWarehouseId}
      />
      <CreateInventory
        open={openInventoryDialog}
        onClose={() => { setOpenInventoryDialog(false); }}
        commodityEntries={commodityEntries}
        supplierEntries={supplierEntries}
        warehouseId={inventoryWarehouseId}
      />
      <ModifyInventory
        open={openModifyDialog}
        onClose={() => { setOpenModifyDialog(false); }}
        commodityEntries={commodityEntries}
        supplierEntries={supplierEntries}
        warehouseId={inventoryWarehouseId}
        modifyEntry={modifyEntry}
      />
    </>
  );
}

export default InventoryManagement;